﻿using CommonLib.Base;
using CommonLib.CodeEntity;
using CommonLib.Util;

namespace Oracle.Read;

public class OracleFilesRead : SqlFilesRead
{
    protected override RootCodeEntity ExecuteLexer(List<string> Lines)
    {
        var entity = new RootCodeEntity();
        var reader = new SqlLineRead();
        reader.Read(Lines);
        while (reader.HasNext)
        {
            entity.Body.Add(SqlFactory.Create(reader.Next).Execute());
        }
        return entity;
    }

    protected override List<string> FormatLines(List<string> Lines)
    {
        var list = new List<string>();
        Lines = Lines.Select(s=> s.Replace("\"","").Replace($"{ConstUtil.DataBase}.","").ReplaceSpace()).ToList();
        for (int i = 0; i < Lines.Count; i++)
        {
            var line = Lines[i];
            if (line.Contains("/*"))
            {
                var sub = new List<string>() { line };
                while (!sub[^1].Contains("*/"))
                {
                    sub.Add(Lines[++i]);
                }
                if (!line.StartsWith("/*"))
                {
                    list.Add(line[..line.IndexOf("/*")].Trim());
                    sub[0] = line[line.IndexOf("/*")..].Trim();
                }
                var last = sub[^1];
                if (!last.EndsWith("*/"))
                {
                    sub[^1] = last[..(last.IndexOf("*/") + 2)].Trim();
                    list.AddRange(sub);
                    list.Add(last[(last.IndexOf("*/") + 2)..].Trim());
                }
                else list.AddRange(sub);
                continue;
            }
            if (line.StartsWith("--"))
            {
                list.Add(line);
                continue;
            }
            if (line.StartsWith("MERGE", true, null) || line.StartsWith("SELECT,", true, null)
                || line.StartsWith("UPDATE,", true, null) || line.StartsWith("INSERT,", true, null)
                || line.StartsWith("DELETE,", true, null))
            {
                list.Add(line);
                while (!list[^1].RealSql().EndsWith(";"))
                {
                    list.Add(Lines[++i]);
                }
                continue;
            }
            var real = line.RealSql();
            while (true)
            {
                if (real.EndsWith(';')) break;
                if (real.EndsWith(" THEN")) break;
                if (real.EndsWith("BEGIN")) break;
                if (real.StartsWith("EXCEPTION")) break;
                if (real.EndsWith("LOOP")) break;
                if(i==Lines.Count-1) break;
                if (line.Contains("--"))
                {
                    var comment = line[(line.IndexOf("--") + 2)..].Trim();
                    comment = $"/*{comment}*/";
                    line = $"{line[..line.IndexOf("--")].Trim()} {comment}";
                }
                line = $"{line} {Lines[++i]}";
                real = line.RealSql();
            }
            if (line.EndsWith(" BEGIN"))
            {
                list.Add(line[..^5].Trim());
                list.Add("BEGIN");
            }
            else list.Add(line);
        }
        return list;
    }
}
